<template>
  <div class="videoBox" :style="{ width: width, height: height }">
    <video
      id="videoElement"
      ref="myElement"
      :controls="true"
      preload="none"
      autoplay
      muted
    ></video>
  </div>
</template>
<script setup name="videoFlv">
import flvjs from "flv.js";
import Hls from "hls.js";
const myElement = ref();
const props = defineProps({
  flvUrl: {
    default: "",
    type: String,
  },
  width: "100%",
  height: "100%",
});
const url = ref("");
// 首先定义flvPlayer为null
const flvPlayer = ref(null);
const createVideo = async () => {
  var videoElement = myElement?.value || null;
  if (!url.value && !videoElement) {
    return;
  }
  if (url.value.includes(".m3u8")) {
    if (Hls.isSupported()) {
      const hls = new Hls();
      hls.loadSource(url.value);
      hls.attachMedia(videoElement);
      flvPlayer.value = hls;
    }
  } else if (url.value.includes(".flv")) {
    if (flvjs.isSupported()) {
      flvPlayer.value = flvjs.createPlayer(
        {
          type: "flv",
          url: url.value, //你的url地址
          isLive: true,
          hasAudio: false,
          hasVideo: true, //数据源是否包含有视频
          enableStashBuffer: false, //是否启用缓存区
        },
        {
          enableWorker: false, //不启用分离线程
          enableStashBuffer: false, //关闭IO隐藏缓冲区
          autoCleanupSourceBuffer: true, //自动清除缓存
        }
      );
      flvPlayer.value?.attachMediaElement(videoElement);
      flvPlayer.value.load();

      // setTimeout(function () {
      //   flvPlayer.value.play();
      // }, 300);
      //处理视频播放错误的语法
      flvPlayer.value.on("error", () => {
        // message.error(`视频加载失败，请稍候重试！`);
        // alert(`视频加载失败，请稍候重试！`);
        return false;
      });
    }
  }
};

// 我的视频是弹窗显示的，所以创建了destroy方法，在子组件中暴露出去后，在父组件调用即可，这样关闭弹窗后，视频流会停止请求。
const setdestroy = () => {
  flvPlayer.value?.pause(); //暂停播放数据流
  flvPlayer.value?.unload(); //取消数据流加载
  flvPlayer.value?.detachMediaElement(); //将播放实例从节点中取出
  flvPlayer.value?.destroy(); //销毁播放实例
  flvPlayer.value = null;
};
defineExpose({ setdestroy });
onMounted(() => {
  nextTick(() => {
    createVideo();
  });
});
watch(
  () => props.flvUrl,
  (val) => {
    url.value = val;
    if (url.value) {
      setdestroy();
      createVideo();
    }
  },
  {
    immediate: true,
    deep: true,
  }
);
</script>
<style scoped>
#videoElement {
  width: 100%;
  height: 100%;
  object-fit: fill;
}
</style>
